const { WebSocket } = require("ws");

module.exports = (server) => {
    //将websocket挂载到 已经创建的端口
    const wss = new WebSocket.Server({
        server,//挂载到原有服务器上，不然你得重新开一个端口，详见文档
        verifyClient
    });


    wss.on('connection', (ws,req) => {
        // 这里可以从 req 里面 取到 userInfo  如果 req.userInfo
        ws.send('恭喜连接成功');
        ws.yoyo = Date.now();
        ws.on('message', (data, isBinary) => {
            console.log(ws.yoyo);
            wss.clients.forEach(client => {
                if (client !== ws && client.readyState === WebSocket.OPEN) {
                    client.send(data, { binary: isBinary });
                }
            });
        });

        ws.on('close', (code) => {
            console.log(ws.yoyo, 'disconnected:', code);
        });

        ws.on('error', (code) => {
            console.log(ws.yoyo, 'error:', code);
        });
    });


    /**
   * 验证连接ws
   * @param {*} info 
   * @returns 
   */
    function verifyClient(info) {
        // 这里实现了 头部和get请求携带  authorization  =  Bearer token...  的token验证
        let headers = info?.req?.headers; 
        if (!headers.authorization) {
            let url = info?.req?.url;
            if (!url) return false;
            let Params = new URLSearchParams(url.replace(/^\//, ''));
            headers.authorization = Params.get("authorization");
        }
        try {
            validates('index', 'token').check(headers);
        } catch (error) {
            return false;
        }
        let userInfo = fun.getToken(String(headers.authorization).split(' ')[1]);
        if (!userInfo) {
            // 登录已过期,请重新登录
            return false;
        }
        // 这里是是从token中获取到了用户信息(写入到了req.userInfo中)  ws连接成功的req里面可以取到该信息
        info.req.userInfo = userInfo;
        return true;
    }

    return async (ctx, next) => {
        ctx.wss = wss;//挂载wss到上下文对象中
        await next();
    };
}